package com.nf;

import com.alibaba.druid.support.opds.udf.SqlCodeStat;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class miniQueryRunner extends miniAbstractQueryRunner{
    public miniQueryRunner() {
        super();
    }


    public miniQueryRunner(boolean pmdKnownBroken) {
        super(pmdKnownBroken);
    }


    public miniQueryRunner(DataSource ds) {
        super(ds);
    }



    public miniQueryRunner(DataSource ds, boolean pmdKnownBroken) {
        super(ds, pmdKnownBroken);
    }

    public int update(Connection conn, String sql) throws SQLException {
        return this.update(conn, false, sql, (Object[]) null);
    }


    public int update(Connection conn, String sql, Object param) throws SQLException {
        return this.update(conn, false, sql, new Object[]{param});
    }


    public int update(Connection conn, String sql, Object... params) throws SQLException {
        return update(conn, false, sql, params);
    }


    public int update(String sql) throws SQLException {
        Connection conn = this.prepareConnection();

        return this.update(conn, true, sql, (Object[]) null);
    }


    public int update(String sql, Object param) throws SQLException {
        Connection conn = this.prepareConnection();

        return this.update(conn, true, sql, new Object[]{param});
    }


    public int update(String sql, Object... params) throws SQLException {
        Connection conn = this.prepareConnection();
        return this.update(conn, true, sql, params);
    }
    private int update(Connection conn, boolean closeConn, String sql, Object... param) throws SQLException {
        if (conn == null) {
            throw new SQLException("Null connection");
        }

        if (sql == null) {
            if (closeConn) {
                close(conn);
            }
            throw new SQLException("Null SQL statement");
        }

        PreparedStatement stmt = null;
        int rows = 0;

        try {
            stmt = this.prepareStatement(conn, sql);
            this.fillStatement(stmt, param);
            rows = stmt.executeUpdate();

        } catch (SQLException e) {
            this.rethrow(e, sql, param);

        } finally {
            close(stmt);
            if (closeConn) {
                close(conn);
            }
        }

        return rows;
    }



    public <T> T query(String sql,MiniResultSetHandler<T> rsh,Object... params)throws SQLException{
        Connection conn = this.prepareConnection();
        return this.<T>query(conn,true,sql,rsh,params);
    }

    public <T> T query(String sql,MiniResultSetHandler<T> rsh)throws SQLException{
        Connection conn=this.prepareConnection();
        return this.<T>query(conn,true,sql,rsh,(Object[])null);
    }

    private <T> T query(Connection conn,boolean closeConn,String sql,MiniResultSetHandler<T> rsh,Object...params)
        throws SQLException{
        if (conn==null){
            throw new SQLException("null connection");
        }
        if (sql==null){
            if (closeConn){
                close(conn);
            }
            throw new SQLException("null sql statement");
        }
        if (rsh==null){
            if (closeConn){
                close(conn);
            }
            throw new SQLException("null resultSetHandler");
        }

        PreparedStatement stmt=null;
        ResultSet rs=null;
        T result=null;

        try{
            stmt=this.prepareStatement(conn,sql);
            this.fillStatement(stmt,params);
            rs=stmt.executeQuery();
            result =  rsh.handle(rs);
        }catch(SQLException e){
            this.rethrow(e,sql,params);
        }finally{
            try{
                close(rs);
            }finally{
                close(stmt);
                if (closeConn){
                    close(conn);
                }
            }
        }
        return result;
    }

}
